﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Web;

namespace Demo.Web.Mvvm
{
    internal class ReflectionCache
    {   
        private static readonly object locker = new object();

        internal static PropertyInfo[] GetProperties(Type type, Type attributeType)
        {
            string key = string.Format("{0}-{1}-{2}", type.Module.Name, type.FullName,
                attributeType == null ? "" : attributeType.ToString());

            PropertyInfo[] properties = HttpRuntime.Cache[key] as PropertyInfo[];
            if (properties == null)
            {
                lock (locker)
                {

                    if (attributeType == null)
                    {
                        properties = type.GetProperties();
                    }
                    else
                    {
                        var props = from property in type.GetProperties()
                                    where property.GetCustomAttributes(attributeType, false).Length > 0
                                    select property;

                        properties = props.ToArray();
                    }
                    
                    HttpRuntime.Cache[key] = properties;
                }
            }

            return properties;
        }


        internal static MethodInfo[] GetMethods(Type type, Type attributeType)
        {
            string key = string.Format("{0}-{1}-{2}", type.Module.Name, type.FullName,
                attributeType == null ? "" : attributeType.ToString());

            MethodInfo[] methods = HttpRuntime.Cache[key] as MethodInfo[];
            if (methods == null)
            {
                lock (locker)
                {
                    if (attributeType == null)
                    {
                        methods = type.GetMethods();
                    }
                    else
                    {
                        var mthds = from method in type.GetMethods(
                                         BindingFlags.DeclaredOnly | BindingFlags.Public | 
                                         BindingFlags.NonPublic | BindingFlags.Instance)
                                    where method.GetCustomAttributes(attributeType, false).Length > 0
                                    select method;

                        methods = mthds.ToArray();
                    }
                    HttpRuntime.Cache[key] = methods;
                }
            }

            return methods;
        }
    }
}
